package org.jeecg.common.util;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.lang.StringUtils;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author lixingxing
 */
@Slf4j
public class OkHttpClientUtil {

    private static OkHttpClient clientInstance;

    private static final Integer CONNECT_TIMEOUT_TIME = 60;

    private static final Integer WRITE_TIMEOUT_TIME = 60;

    private static final Integer READ_TIMEOUT_TIME = 60;

    static {
        if (clientInstance == null) {
            clientInstance = new OkHttpClient.Builder().connectTimeout(CONNECT_TIMEOUT_TIME, TimeUnit.SECONDS).writeTimeout(WRITE_TIMEOUT_TIME, TimeUnit.SECONDS).readTimeout(READ_TIMEOUT_TIME, TimeUnit.SECONDS).retryOnConnectionFailure(true).build();
        }
    }

    public static <T> T formBody(String url, Map<String, String> params, Class<T> clz) {
        log.info("请求参数:{}", JSON.toJSONString(params));
        FormBody.Builder builder = new FormBody.Builder();
        params.forEach((k, v) -> builder.add(k, v));
        FormBody body = builder.build();
        if (String.class == clz) {
            return (T) toString(url, body, "POST");
        }
        return JSON.parseObject(toString(url, body, "POST"), clz);
    }

    public static <T> T requestBody(String url, Object o, Class<T> clz) {
        log.info("请求参数:{}", JSON.toJSONString(o));
        RequestBody body = RequestBody.create(MediaType.parse("application/json;charset=utf-8"), JSON.toJSONString(o));
        if (String.class == clz) {
            return (T) toString(url, body, "POST");
        }
        return JSON.parseObject(toString(url, body, "POST"), clz);
    }

    public static <T> T requestBody(String url, String o, Class<T> clz) {
        log.info("请求参数:{}", JSON.toJSONString(o));
        RequestBody body = RequestBody.create(MediaType.parse("application/json;charset=utf-8"), o);
        if (String.class == clz) {
            return (T) toString(url, body, "POST");
        }
        return JSON.parseObject(toString(url, body, "POST"), clz);
    }

    public static <T> T get(String url, Class<T> clz) {
        if (String.class == clz) {
            return (T) toString(url, null, "GET");
        }
        return JSON.parseObject(toString(url, null, "GET"), clz);
    }

    public static Response get(String url) {
        return execute(url, null, "GET");
    }

    public static byte[] getBytes(String url) {
        return getBytes(url, null, "GET");
    }

    private static String toString(String url, RequestBody body, String method) {
        try (Response response = execute(url, body, method)) {
            String data = response.body().string();
            log.info("请求结果:{}", data);
            return data;
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    private static Response execute(String url, RequestBody body, String method) {
        Request request = null;
        boolean flag = StringUtils.equals("GET", method);
        if (flag) {
            request = new Request.Builder().get().url(url).build();
        } else {
            request = new Request.Builder().post(body).url(url).build();
        }
        Response response = null;
        try {
            response = clientInstance.newCall(request).execute();
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        return response;
    }

    private static byte[] getBytes(String url, RequestBody body, String method) {
        try (ResponseBody responseBody = execute(url, body, method).body()) {
            return responseBody.bytes();
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }
}
